﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
using System.IO;

namespace Lyh.MyQQListView.Util
{
    /// <summary>
    /// Rich Text Format (RTF) 帮助类
    /// </summary>
    public class RtfHelper
    {
        #region --私有变量--

        private readonly string filePath;
        private SortedList<string, Image> images;

        #endregion

        #region --公有属性--

        public string FilePath
        {
            get { return filePath; }
        }

        #endregion

        #region --构造方法--

        public RtfHelper(string directory)
        {
            filePath = directory;
            images = new SortedList<string, Image>();
        }

        #endregion

        #region --公有方法--

        /// <summary>
        /// 保存RTF文本中的图片
        /// </summary>
        /// <param name="rtf">rtf文本</param>
        /// <returns>图片集合</returns>
        public SortedList<string, Image> SaveRtfImage(ref string rtf)
        {
            ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Png);
            System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
            EncoderParameters myEncoderParameters = new EncoderParameters(1);
            EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 100L);
            myEncoderParameters.Param[0] = myEncoderParameter;

            MatchCollection mc = Regex.Matches(rtf, @"\{\\pict[^\}]+}");
            foreach (Match mat in mc)
            {
                Match picw = Regex.Match(mat.Value, @"picwgoal[\d]+");
                Match pich = Regex.Match(mat.Value, @"pichgoal[\d]+");
                //图片的宽
                int width = (int)Math.Round(int.Parse(picw.Value.Replace("picwgoal", "")) / 15.00);
                //图片的高
                int height = (int)Math.Round(int.Parse(pich.Value.Replace("pichgoal", "")) / 15.00);
                //图片数据
                string rtfImage = mat.Value.Substring(pich.Index + pich.Length).Replace("\r\n", "").Replace(" ", "").Replace("}", "");
                int count = rtfImage.Length / 2;
                byte[] buffer = new byte[count];
                for (int i = 0; i < count; i++)
                {
                    buffer[i] = Convert.ToByte(rtfImage.Substring(i * 2, 2), 16);
                }
                //保存图片
                using (MemoryStream ms = new MemoryStream(buffer))
                {
                    using (Bitmap bmpms = new Bitmap(ms, true))
                    {
                        using (Bitmap bmp = new Bitmap(bmpms, width, height))
                        {
                            string fileid = Guid.NewGuid().ToString();
                            string filename = string.Format(@"{0}\{1}.{2}", filePath, fileid, "png");
                            bmp.Save(filename, jpgEncoder, myEncoderParameters);
                            images[fileid] = bmp;
                            rtf = rtf.Replace(mat.Value, string.Format(@"{{\*\atnid {0}}}", fileid));
                        }
                    }
                }
            }

            return images;
        }

        /// <summary>
        /// 获得图片的RTF文本
        /// </summary>
        /// <param name="image">图片</param>
        /// <returns>RTF文本</returns>
        public string GetRtfImage(Image image)
        {
            StringBuilder sbRtfImage = new StringBuilder();

            MemoryStream ms = new MemoryStream();
            image.Save(ms, image.RawFormat);
            byte[] buffer = ms.ToArray();
            foreach (byte b in buffer)
            {
                sbRtfImage.Append(string.Format("{0:X2}", b));
            }

            return sbRtfImage.ToString();
        }

        #endregion

        #region --私有方法--

        private ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }

        #endregion

    }
}
